var app = app || {};

$(function () {
    console.log("DOM ready");
    app.isTest = true;
    app.clientTournament = null;
    app.socket = io('http://localhost:8080');
    app.socket.on('connect', function () {
        if (!(uuid = sessionStorage.getItem('uuid'))) {
            var randomlyGeneratedUID = Math.random().toString(36).substring(3, 16) + +new Date;
            sessionStorage.setItem('uuid', randomlyGeneratedUID);
        }
        app.socket.emit('register', sessionStorage.getItem('uuid'));
        //Listner einbinden
        //Server bestätigt die Verbindung des neuen Clients
        //app.socket.on('confirmNewConnection', confirmNewConnection);

        //Wird die Liste der laufenden Turniere geändert oder jemand wird auf die Übersicht geleitet
        app.socket.on('initTournamentList', app.Client.initTournamentList);
        //Ist ein turnier dazugekommen oder geschlossen wurden
        app.socket.on('refreshTournamentList', app.Client.refreshTournamentList)
            //Wird ein ErgebnisS eingetragen oder für einen Zuschauer, der beigetreten ist
        app.socket.on('initTournament', app.Client.initTournament);
        //Wird ein Turnier beendet
        app.socket.on('gameover', app.Client.gameover);
        //hat der Adminsitrator eines neues Turnier gestartet oder die Bearbeitung aufgenommen
        app.socket.on('confirmTournamentAdmin', app.Client.confirmTournamentAdmin);
        //Server  weist admin-Login zurück
        app.socket.on('accessDenied', app.Client.accessDenied);
        //Änderung im Turnier
        app.socket.on('changeEvent', app.Client.changeEvent);
        //Änderung in den Spielen
        app.socket.on('changedGames', app.Client.changeGames);
        //Allgemeine Fehlermeldung
        app.socket.on('errorMessage', app.Client.errorHandling);

        app.socket.on('stats', function (count) {
            //console.log(count);
        });

        app.socket.on('errorTabs', function (data) {
            console.log("Empfange Fehlermeldung: " + data.message);
            //app.Navigation.showError(data.message);
        });
    });
    //weitere inits aufrufen
    app.Navigation.init();
});
app.Client = {

    changeGames: function (changedGames) {
        console.log("Empfange: Spieleänderung")
        for (var i = 0; i < changedGames.length; i++) {
            //console.log("Spiel " + (parseInt(changedGames[i].index) + 1));
            //console.log(changedGames[i].game);
            app.clientTournament.gameList[changedGames[i].index] = changedGames[i].game;
            app.TournamentViews.refreshGameTableGame(changedGames[i].index);
        }
    },

    errorHandling: function (data) {
        console.log("Empfange: Fehlermeldung");
        app.Navigation.showError(data.message);
    },

    changeEvent: function (data) {
        console.log("Empfange: ÄnderungsLog")
        app.Navigation.recieveChange(data);
    },

    initTournamentList: function (tList) {
        console.log("Empfange: Init tournamentList");
        app.Navigation.initTournamentList(tList);
        //TODO Liste zum anzeigen aller Turniere an die entsprechende Stelle weitergeben
    },

    refreshTournamentList: function (data) {
        console.log("Empfange: Refresh tournamentList");
        app.Navigation.refreshTournamentList(data.id, data.name);
    },

    initTournament: function (tournament) {
        console.log("Empfange: Refresh Turnier");
        app.clientTournament = tournament;
        app.Navigation.initTournament();
        //funktionen zum aktualisieren aufrufen
    },

    gameover: function () {
        //Reconnect
        app.Navigation.gameover();
        //automatisches verlassen vs. manuelles verlassen
        app.Client.leaveTournament();
        console.log("Empfange: Gameover");
    },

    confirmTournamentAdmin: function () {
        //Bearbeitenansicht freischalten
        if (app.clientTournament != null) {
            app.Navigation.confirmTournamentAdmin();
        }
    },

    accessDenied: function (errString) {
        console.log("Empfange: Zugang verweigert: " + errString);
    },

    //Funktionen die ein Event an den Server senden

    joinTournament: function (tournamentID) {
        console.log("Aufruf: Join Tournament");
        if (!app.socket.disconnected) {
            app.socket.emit('joinTournament', tournamentID);
        } else {
            //
        }
    },

    adminExistingTournament: function (tournamentID, adminPass) {
        //TODO
        console.log("Aufruf: Admin Existing Tournament");
        console.log("ID: " + tournamentID + "pass " + adminPass);
        app.socket.emit('adminExistingTournament', {
            tournamentID: tournamentID,
            adminPass: adminPass
        });
    },

    adminNewTournament: function (tournamentName, adminPass, competitors) {
        //TODO (zB Passwort Hashen)
        console.log("Aufruf: AdminNewTournament");
        app.socket.emit('adminNewTournament', {
            tournamentName: tournamentName,
            competitors: competitors,
            adminPass: adminPass
        });
    },

    setScoreInGame: function (gameIndex, score1, score2) {
        console.log("Aufruf: Setze Ergebnis");
        if (!app.socket.disconnected) {
            app.socket.emit('setScoreInGame', {
                gameIndex: gameIndex,
                score1: score1,
                score2: score2
            });
        } else {
            app.offlineModus.setScoreInGame(gameIndex, score1, score2);
        }
    },

    leaveTournament: function () {
        //TODO 
        //ggf nicht über emit sonder über app.socket disconnect und connect
        //
        console.log("Aufruf: Leave Tournament");
        app.socket.emit('leaveTournament');
    },

    quitTournament: function () {
        //TODO
        console.log("Aufruf: Quit Tournament");
        app.socket.emit('quitTournament');
    },

    // weitere bereitgestellte Funktionen

    getLosersbracketRound: function (i) {
        if (i <= app.clientTournament.losersbracketRoundNumber) {
            var toGame = 0;
            var fromGame = 0;
            for (var x = 1; x <= i; x++) {
                var tmpX = Math.floor((x + 1) / 2 + 1);
                fromGame = toGame + 1;
                toGame = toGame + Math.floor(app.clientTournament.fieldSize / Math.pow(2, tmpX));
            }
            var tmp = [];
            for (var x = 0; x < (toGame - fromGame + 1); x++) {
                tmp[x] = app.clientTournament.losersbracket[x + fromGame - 1];
            }
            return tmp;
        } else {
            return null;
        }
    },

    getWinnersbracketRound: function (i) {
        if (i <= app.clientTournament.winnersbracketRoundNumber) {
            var sumGames = Math.pow(2, app.clientTournament.winnersbracketRoundNumber - i);
            var toGame = Math.pow(2, app.clientTournament.winnersbracketRoundNumber) * (1 - Math.pow(2, -i));
            var fromGame = toGame - sumGames + 1;
            var tmp = [];
            for (var x = 0; x < sumGames; x++) {
                tmp[x] = app.clientTournament.winnersbracket[x + fromGame - 1];
            }
            return tmp;
        } else {
            return null;
        }
    }
};

app.offlineModus = {
    setScoreInGame: function (gameIndex, score1, score2) {
        console.log("Aufruf: Set Score in Game - Offline");
        if (gameIndex && score1 && score2) {
            if (app.clientTournament.gameList[gameIndex].player1 > -1 && app.clientTournament.gameList[gameIndex].player2 > -1) {
                var changes = setResAndGetChanges(gameIndex, score1, score2);
                if (changes) {
                    app.Client.deltaList = app.Client.deltaList || [];
                    app.Client.deltaList.push({
                        changedGames: changes,
                        time: new Date()
                    });
                    //Turnier zurücksenden
                    //io.sockets.in(tournamentID).emit('initTournament', tournament);
                    //Spiele die geändert wurden senden
                    app.Client.changeGames(changes);
                    //io.sockets.in(tournamentID).emit('changedGames', changes);
                    //ChangeEvent senden
                    var d = new Date();
                    app.Client.changeEvent({
                        date: d.toLocaleTimeString(),
                        spiel: gameIndex,
                        winner: app.clientTournament.competitorsList[Game.getWinner(app.clientTournament.gameList[gameIndex])],
                        res: score1 + ' : ' + score2
                    });
                    /*io.sockets.in(tournamentID).emit('changeEvent', {
                        date: d.toLocaleTimeString(),
                        spiel: gameIndex,
                        winner: tournament.competitorsList[Game.getWinner(tournament.gameList[gameIndex])],
                        res: score1 + ' : ' + score2
                    });
                    */
                } else {
                    console.log("Fehler beim speichern des Turniers");
                    app.Client.errorHandling({
                        message: 'Fehler beim Setzen des Ergebnisses'
                    });
                }
            } else {
                console.log("Falsche Eingabe: Spiele mit Freilosen können nicht bearbeitet werden.");
                app.Client.errorHandling({
                    message: 'Falsche Eingabe: Spiele mit Freilosen können nicht bearbeitet werden.'
                });
            }
        } else {
            console.log("Fehlerhafte Daten als Input");
            app.Client.errorHandling({
                message: 'Bitte die Eingabe überprüfen. Keine negativen Ergebnisse zugelassen. Kein Gleichstand ist erlaubt. Spiele die ein Freilos enthalten können nicht bearbeitet werden.'
            });

            function setResAndGetChanges(gameIndex, score1, score2) {
                if (app.clientTournament == undefined ||
                    app.clientTournament == null ||
                    gameIndex < 0 ||
                    score1 < 0 ||
                    score2 < 0 ||
                    app.clientTournament.gameList[gameIndex].player1 == null ||
                    app.clientTournament.gameList[gameIndex].player2 == null ||
                    score1 == score2) {
                    return false;
                }
                var changedGames = [];
                app.clientTournament.gameList[gameIndex].scorePlayer1 = score1;
                app.clientTournament.gameList[gameIndex].scorePlayer2 = score2;
                changedGames.push({
                    index: gameIndex,
                    game: app.clientTournament.gameList[gameIndex]
                });
                for (var i = 0; i < app.clientTournament.gameList.length; i++) {
                    var tmpGame = app.clientTournament.gameList[i];
                    if (tmpGame.source1 != null && tmpGame.source1.game == gameIndex) {
                        if (tmpGame.source1.asWinner) {
                            tmpGame.player1 = Game.getWinner(app.clientTournament.gameList[gameIndex]);
                        } else {
                            tmpGame.player1 = Game.getLoser(app.clientTournament.gameList[gameIndex]);
                        }
                        changedGames.push({
                            index: i,
                            game: tmpGame
                        });
                        if (tmpGame.player2 == -1) {
                            var concat = Tournament.setResAndGetChanges(i, 1, 0);
                            if (concat == false) {
                                return false;
                            }
                            concat.shift();
                            changedGames = changedGames.concat(concat);
                        }
                    } else if (tmpGame.source2 != null && tmpGame.source2.game == gameIndex) {
                        if (tmpGame.source2.asWinner) {
                            tmpGame.player2 = Game.getWinner(app.clientTournament.gameList[gameIndex]);
                        } else {
                            tmpGame.player2 = Game.getLoser(app.clientTournament.gameList[gameIndex]);
                        }
                        changedGames.push({
                            index: i,
                            game: tmpGame
                        });
                        if (tmpGame.player1 == -1) {
                            var concat = Tournament.setResAndGetChanges(i, 0, 1);
                            if (concat == false) {
                                return false;
                            }
                            concat.shift();
                            changedGames = changedGames.concat(concat);
                        }
                    }
                }
                return changedGames;
            }

        }


    }
}